package com.hbk.programe;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Modular {

	private String clazz;
	
	private String clazzAlias;

	private String table;

	private String alias;

	private String comment;

	private List<Field> fields = new ArrayList<Field>();

	private List<Method> methods = new ArrayList<Method>();

	private List<Dto> dtos = new ArrayList<Dto>();

	private PageConfig page = new PageConfig();;

	private List<Modular> pojos = new ArrayList<Modular>();

	public String getClazz() {
		return clazz;
	}

	public void setClazz(String clazz) {
		this.clazz = clazz;
	}

	public String getClazzAlias() {
		return clazzAlias;
	}

	public void setClazzAlias(String clazzAlias) {
		this.clazzAlias = clazzAlias;
	}

	public String getTable() {
		return table;
	}

	public void setTable(String table) {
		this.table = table;
	}

	public String getAlias() {
		return alias;
	}

	public void setAlias(String alias) {
		this.alias = alias;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public List<Field> getFields() {
		return fields;
	}

	public void setFields(List<Field> fields) {
		this.fields = fields;
	}

	public List<Method> getMethods() {
		return methods;
	}

	public void setMethods(List<Method> methods) {
		this.methods = methods;
	}

	public List<Dto> getDtos() {
		return dtos;
	}

	public void setDtos(List<Dto> dtos) {
		this.dtos = dtos;
	}

	public PageConfig getPage() {
		return page;
	}

	public void setPage(PageConfig page) {
		this.page = page;
	}

	public Page parsePages(boolean isPage) {
		PageConfig config = getPage();
		if(config.getNamespace()==null) {
			return null;
		}
		Page page = new Page();
		page.setPattern(config.getPattern());
		page.setNamespace(config.getNamespace());
		page.setUrl(config.getUrl());
		page.setApi(config.getApi());
		List<String> columns = config.getColumns();
		if(columns.size()==0) {
			for (Field field : getFields()) {
				if(field.getName().equals("id")) {
					continue;
				}
				Column col = new Column();
				col.setTitle(field.getComment());
				col.setConstant(field.getConstant());
				col.setRender(field.getConstant().size() > 0);
				col.setAlign(field.getType().equals("String"));
				col.setName(field.getName());
				col.setFormType(field.getForm());
				page.getColumns().add(col);
			}
		}else {
			for (String column : columns) {
				String columnAlias = null;
				if (column.indexOf(" ") != -1) {
					String[] arr = column.split(" ");
					column = arr[0];
					columnAlias = arr[1];
				}
				for (Modular pojo : getPojos()) {
					if (column.startsWith(pojo.getClazz() + ".")) {
						for (Field field : pojo.getFields()) {
							if (field.getName().equals(column.replaceAll(pojo.getClazz() + ".", ""))) {
								Column col = new Column();
								col.setTitle(field.getComment());
								col.setConstant(field.getConstant());
								col.setRender(field.getConstant().size() > 0);
								col.setAlign(field.getType().equals("String"));
								if (columnAlias != null) {
									col.setName(columnAlias);
								} else {
									col.setName(field.getName());
								}
								col.setFormType(field.getForm());
								page.getColumns().add(col);
								break;
							}
						}
						break;
					}
				}
			}
		}
		
		List<String> filters = config.getFilters();
		for (String filter : filters) {
			for (Dto dto : dtos) {
				if (filter.startsWith(dto.getClazz() + ".")) {
					for (DtoField dtoField : dto.getFields()) {
						if (dtoField.getName().equals(filter.replaceAll(dto.getClazz() + ".", ""))) {
							Field field = getRefField(dtoField.getRef());
							Form formItem = new Form();
							formItem.setTitle(field.getComment());
							formItem.setName(dtoField.getName());
							formItem.setType(field.getForm());
							formItem.setConstant(field.getConstant());
							if(field.getForm().equals("DataList")) {
								Modular pojo=getPojo(field.getType());
								if(pojo!=null&&pojo.parsePages(false)!=null) {
									Page dataListPage =pojo.parsePages(false);
									formItem.setApi(dataListPage.getApi());
									formItem.setNamespace(page.getNamespace()+StringUtil.capitalize(formItem.getName()));
									formItem.setColumns(dataListPage.getColumns());
									formItem.setFilters(dataListPage.getFilters());
								}
								
							}
							page.getFilters().add(formItem);
						}
					}
				}
			}
		}
		
		if(!isPage) {
			return page;
		}

		List<String> fields = config.getFields();
		if(fields.size()==0) {
			for (Field field : getFields()) {
				if(field.getName().equals("id")) {
					continue;
				}
				Form formItem = new Form();
				formItem.setTitle(field.getComment());
				formItem.setName(field.getName());
				formItem.setType(field.getForm());
				formItem.setConstant(field.getConstant());
				page.getForms().add(formItem);
			}
		}else {
			for (String ref : fields) {
				for (Modular pojo : getPojos()) {
					if (ref.startsWith(pojo.getClazz() + ".")) {
						for (Field field : pojo.getFields()) {
							if (field.getName().equals(ref.replaceAll(pojo.getClazz() + ".", ""))) {
								Form formItem = new Form();
								formItem.setTitle(field.getComment());
								formItem.setName(field.getName());
								formItem.setType(field.getForm());
								formItem.setConstant(field.getConstant());
								if(field.getForm().equals("DataList")) {
									Modular dataListPojo=getPojo(field.getType());
									if(dataListPojo!=null&&dataListPojo.parsePages(false)!=null) {
										Page dataListPage =dataListPojo.parsePages(false);
										formItem.setApi(dataListPage.getApi());
										formItem.setNamespace(config.getNamespace()+StringUtil.capitalize(field.getName()));
										formItem.setColumns(dataListPage.getColumns());
										formItem.setFilters(dataListPage.getFilters());
									}
								}else if(field.getForm().equals("Table")) {
									List<FieldColumn> fieldColumns=field.getColumns();
									List<Column> cols=new ArrayList<>();
									for (FieldColumn fieldColumn : fieldColumns) {
										String columnRef=fieldColumn.getRef();
										String columnAlias="";
										if (fieldColumn.getRef().indexOf(" ") != -1) {
											String[] arr = fieldColumn.getRef().split(" ");
											columnRef = arr[0];
											columnAlias = arr[1];
										}
										Field refField=getRefField(columnRef);
										Column column=new Column();
										column.setTitle(refField.getComment());
										column.setName(columnAlias==""?refField.getName():columnAlias);
										column.setConstant(refField.getConstant());
										column.setAlign(refField.getType().equals("String"));
										column.setRender(fieldColumn.getEditable());
										column.setFormType(fieldColumn.getForm());
										if(fieldColumn.getForm().equals("DataList")) {
											Form form=new Form();
											Modular dataListPojo=getPojo(field.getType());
											if(dataListPojo!=null&&dataListPojo.parsePages(false)!=null) {
												Page dataListPage =dataListPojo.parsePages(false);
												form.setApi(dataListPage.getApi());
												formItem.setNamespace(field.getName()+StringUtil.capitalize(column.getName()));
												form.setColumns(dataListPage.getColumns());
												form.setFilters(dataListPage.getFilters());
											}
											column.setForm(form);
										}
										cols.add(column);
									}
									formItem.setColumns(cols);
								}
								page.getForms().add(formItem);
							}
						}
						break;
					}
				}
			}
		}

		return page;
	}

	public Set<String> getImports() {
		Set<String> list = new HashSet<>();
		for (Field field : fields) {
			if (field.getType().equals("BigDecimal")) {
				list.add("import java.math.BigDecimal;");
			}
			if (field.getType().equals("Date")) {
				list.add("import java.util.Date;");
			}
			if (field.getType().contains("List")) {
				list.add("import java.util.List;");
				list.add("import java.util.ArrayList;");
			}
			if (field.getType().equals("Set")) {
				list.add("import java.util.Set;");
				list.add("import java.util.HashSet;");
			}
		}
		return list;
	}

	public String getFetch(String ref) {
		String type = "";
		for (Modular pojo : getPojos()) {
			if (ref.startsWith(pojo.clazz + ".")) {
				for (Field field : pojo.getFields()) {
					if (ref.endsWith(field.getName())) {
						return field.getFetch();
					}
				}
			}
		}
		return type;
	}

	public Field getRefField(String ref) {
		Field target=null;
		String[] arr=ref.split("\\.");
		String root=arr[0];
		for(int i=1;i<arr.length;i++) {
			String fieldRef=StringUtil.capitalize(root)+"."+arr[i];
			for (Modular pojo : getPojos()) {
				if (ref.startsWith(pojo.clazz + ".")) {
					for (Field field : pojo.getFields()) {
						if (fieldRef.endsWith("."+field.getName())) {
							target=field;
						}
					}
				}
			}
			if(i<=arr.length-1) {
				root=target.getType();
			}
		}
		
		return target;
	}

	public String getRefType(String ref) {
		
		String type = "";
		for (Modular pojo : getPojos()) {
			if (ref.startsWith(pojo.clazz + ".")) {
				for (Field field : pojo.getFields()) {
					if (ref.endsWith(field.getName())) {
						type = field.getType();
					}
				}
			}
		}
		if (type.equals("")) {
			throw new RuntimeException("找不到对应的field:"+ref);
		}
		return type;
	}

	public List<DtoField> getQueryCondition(List<Param> params) {
		List<DtoField> result=new ArrayList<DtoField>();
		for(Param param:params) {
			for (Dto dto : dtos) {
				if (dto.getClazz().equals(param.getType())) {
					for (DtoField dtofield : dto.getFields()) {
						for (Modular pojo : getPojos()) {
							if (dtofield.getRef().length()>0&&dtofield.getRef().startsWith(pojo.getClazz() + ".")) {
								for (Field field : pojo.getFields()) {
									if (dtofield.getRef().endsWith("." + field.getName())) {
										
										dtofield.setRefColumn(pojo.getAlias() + "." + field.getColumn());
										dtofield.setRefName(field.getName());
										dtofield.setVar(param.getVar());
										result.add(dtofield);
									}
								}
							}
						}
					}
				}
			}
		}
		for(Param param:params) {
			if(param.getRef()!=null) {
				for (Modular pojo : getPojos()) {
					if (param.getRef().startsWith(pojo.getClazz() + ".")) {
						for (Field field : pojo.getFields()) {
							if (param.getRef().endsWith("." + field.getName())) {
								DtoField dtofield=new DtoField();
								dtofield.setType(param.getType());
								dtofield.setName(param.getVar());
								dtofield.setDto(false);
								dtofield.setRefColumn(pojo.getAlias() + "." + field.getColumn());
								dtofield.setRefName(field.getName());
								dtofield.setVar(param.getVar());
								result.add(dtofield);
							}
						}
					}
				}
			}
		}
		
		return result;
	}

	public String stripClazz(String type) {
		return type.substring(type.indexOf("<") + 1, type.indexOf(">"));
	}

	public List<DtoField> getDtoField(String clazz) {
		for (Dto dto : dtos) {
			if (dto.getClazz().equals(clazz)) {
				return dto.getFields();
			}
		}
		return new ArrayList<DtoField>();
	}

	public List<Modular> getPojos() {
		return pojos;
	}

	public void setPojos(List<Modular> pojos) {
		this.pojos = pojos;
	}
	
	public Boolean isPojo(String clazz){
		for (Modular pojo : getPojos()) {
			if(pojo.getClazz().equals(clazz)) {
				return true;
			}
		}
		return false;
	}
	
	public Modular getPojo(String clazz) {
		for (Modular pojo : getPojos()) {
			if(pojo.getClazz().equals(clazz)) {
				pojo.setPojos(this.getPojos());
				return pojo;
			}
		}
		return null;
	}
	
	public Dto getDto(String clazz) {
		for (Dto dto : dtos) {
			if (dto.getClazz().equals(clazz)) {
				for (DtoField dtofield : dto.getFields()) {
					for (Modular pojo : getPojos()) {
						if (dtofield.getRef().startsWith(pojo.getClazz() + ".")) {
							for (Field field : pojo.getFields()) {
								if (dtofield.getRef().endsWith("." + field.getName())) {
									dtofield.setRefColumn(pojo.getAlias() + "." + field.getColumn());
									dtofield.setRefName(field.getName());
								}
							}
						}
					}
				}
				return dto;
			}
		}
		return new Dto();
	}

	public String getTable(String clazz) {
		String table = "";
		for (Modular pojo : getPojos()) {
			if (clazz.equals(pojo.clazz)) {
				table = pojo.getTable();
			}
		}
		if (table.equals("")) {
			throw new RuntimeException("找不到要left join 的表");
		}
		return table;
	}

	public String getAlias(String clazz) {
		String table = "";
		for (Modular pojo : getPojos()) {
			if (clazz.equals(pojo.clazz)) {
				table = pojo.getAlias();
			}
		}
		if (table.equals("")) {
			throw new RuntimeException("请给类加上别名");
		}
		return table;
	}

	public String getOrder(List<String> columns) {
		StringBuffer attr = new StringBuffer();
		for (String column : columns) {
			for (Modular pojo : getPojos()) {
				if (column.startsWith(pojo.getClazz() + ".")) {
					for (Field field : pojo.getFields()) {
						if (field.getName().equals(column.replaceAll(pojo.getClazz() + ".", ""))) {
							attr.append(pojo.getAlias()).append(".").append(field.getColumn()).append(",");
						}
					}
				}
			}
		}
		return attr.delete(attr.length() - 1, attr.length()).toString();
	}


	public String getSql(List<String> columns) {
		StringBuffer attr = new StringBuffer();
		StringBuffer sql = new StringBuffer("select ");
		AliasCount count=new AliasCount();
		for (String column : columns) {
			String columnAlias = null;
			if (column.indexOf(" ") != -1) {
				String[] arr = column.split(" ");
				column = arr[0];
				columnAlias = arr[1];
			}
			
			String[] arr=column.split("\\.");
			
			if(arr.length==1) {
				attr.append(column).append(columnAlias == null ? "," : " " + columnAlias + ",");
			}else if(arr.length==2){
				Modular pojo=getPojo(arr[0]);
				String alias=count.getAlias(pojo.getClazz(), pojo.getAlias());
				for (Field field : pojo.getFields()) {
					if (field.getName().equals(column.replaceAll(pojo.getClazz() + ".", ""))) {
						if (field.getName().equals(field.getColumn())) {
							if (field.getDataType().equals("DATE")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							} else if (field.getDataType().equals("DATETIME")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							} else {
								
								attr.append(alias).append(".").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							}
						} else {
							if (field.getDataType().equals("DATE")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							
							} else if (field.getDataType().equals("DATETIME")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							
							} else if (field.getColumn().endsWith("_id")) {
								
								attr.append(alias).append(".").append(field.getColumn()).append(" ").append(columnAlias == null ? field.getName() + "Id" : columnAlias).append(",");
							
							} else {
								
								attr.append(alias).append(".").append(field.getColumn()).append(" ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							}
						}
					}
				}
			}else if(arr.length>2) {
				String ref="";
				for(int i=arr.length-2;i>=0;i--) {
					if(ref.length()>0) {
						ref=arr[i]+"."+ref;
					}else {
						ref=arr[i];
					}
				}
				String clazz=arr[0];
				for(int i=1;i<=arr.length-2;i++) {
					clazz=getRefType(StringUtil.capitalize(clazz)+"."+arr[i]);
				}
				
				Modular pojo=getPojo(clazz);
				
				String alias=count.getAlias(ref,pojo.getAlias());
								
				String fieldName=arr[arr.length-1];
				
				for (Field field : pojo.getFields()) {
					if (field.getName().equals(fieldName)) {
						if (field.getName().equals(field.getColumn())) {
							if (field.getDataType().equals("DATE")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							} else if (field.getDataType().equals("DATETIME")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							} else {
								
								attr.append(alias).append(".").append(field.getName()).append(columnAlias == null ? "," : " " + columnAlias + ",");
							
							}
						} else {
							if (field.getDataType().equals("DATE")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							
							} else if (field.getDataType().equals("DATETIME")) {
								
								attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							
							} else if (field.getColumn().endsWith("_id")) {
								
								attr.append(alias).append(".").append(field.getColumn()).append(" ").append(columnAlias == null ? field.getName() + "Id" : columnAlias).append(",");
							
							} else {
								
								attr.append(alias).append(".").append(field.getColumn()).append(" ").append(columnAlias == null ? field.getName() : columnAlias).append(",");
							}
						}
					}
				}
			}
		}
		
		if (attr.length() == 0) {
			String alias=count.getAlias(this.getClazz(), this.getAlias());
			for (Field field : getFields()) {
				if (field.getName().equals(field.getColumn())) {
					if (field.getDataType().equals("DATE")) {
						attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(field.getName()).append(",");
					} else if (field.getDataType().equals("DATETIME")) {
						attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(field.getName()).append(",");
					} else {
						attr.append(alias).append(".").append(field.getName()).append(",");
					}
				} else {
					if (field.getDataType().equals("DATE")) {
						attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d'").append(") ").append(field.getName()).append(",");
					} else if (field.getDataType().equals("DATETIME")) {
						attr.append("DATE_FORMAT(").append(alias).append(".").append(field.getColumn()).append(",").append("'%Y-%m-%d %H:%i:%s'").append(") ").append(field.getName()).append(",");
					} else if (field.getColumn().endsWith("_id")) {
						attr.append(alias).append(".").append(field.getColumn()).append(" ").append(field.getName()).append("Id").append(",");
					} else {
						attr.append(alias).append(".").append(field.getColumn()).append(" ").append(field.getName()).append(",");
					}
				}
			}
		}
		
		sql.append(attr.delete(attr.length() - 1, attr.length()));
		
		StringBuffer leftjoin=new StringBuffer();
		Map<String,String> map=count.getMap();
		Object[] os=map.keySet().toArray();
		Arrays.sort(os);
		Modular root=getPojo(os[0].toString());
		leftjoin.append( root.getTable() ).append(" ").append( map.get(os[0].toString()) );
		if(os.length>1) {
			for(int i=1;i<os.length;i++) {
				String refPath=os[i].toString();
				String[] arr=refPath.split("\\.");
				if(arr.length>2) {
					Modular parent=getPojo(StringUtil.capitalize(arr[arr.length-2]));
					Field refField=getRefField(StringUtil.capitalize(arr[arr.length-2])+"."+arr[arr.length-1]);
					Modular child=getPojo(StringUtil.capitalize(arr[arr.length-1]));
					leftjoin.append(" left join ").append(child.getTable()).append(" ").append(map.get(os[i].toString())).append(" on ").append(map.get(os[i].toString())).append(".id=").append(map.get(os[i-1].toString())).append(".").append(refField.getColumn()) ;
				}else {
					String clazz=getRefType(refPath);
					Field refField=getRefField(refPath);
					Modular child=getPojo(clazz);
					leftjoin.append(" left join ").append(child.getTable()).append(" ").append(map.get(os[i].toString())).append(" on ").append(map.get(os[i].toString())).append(".id=").append(map.get(os[0].toString())).append(".").append(refField.getColumn()) ;
				}
			}
		}
		
		sql.append(" from ").append(leftjoin);
		sql.append(" where 1=1");
		return sql.toString();
	}

	public String getGenerateCode(String methodName) {
		List<Declare> context = new ArrayList<>();
		for (Modular pojo : getPojos()) {
			for (Field field : pojo.getFields()) {
				context.add(new Declare(field.getType(), field.getName(), pojo.getClazz() + "." + field.getName(), ""));
			}
		}
		for (Dto dto : getDtos()) {
			for (DtoField field : dto.getFields()) {
				context.add(new Declare(field.getType(), field.getName(), dto.getClazz() + "." + field.getName(),
						field.getRef()));
			}
		}
		String n = "\\n";
		String l = " ";
		StringBuffer code = new StringBuffer();
		List<Line> lines = new ArrayList<Line>();
		for (Method method : methods) {
			if (method.getName().equals(methodName)) {
				for (Param param : method.getParams()) {
					context.add(new Declare(param.getType(), param.getVar(), "", ""));
				}
				for (String content : method.getColumns()) {
					int level = 0;
					for (int i = 2; i < content.length(); i++) {
						String ch = content.substring(i, i + 1);
						if (ch.equals(l)) {
							level++;
						} else {
							break;
						}
					}
					if (content.startsWith(">>")) {
						Line line = new Line(content.substring(2), true, level + 2);
						putLine(lines, level, line);
					} else {
						Line line = new Line(content.substring(2), false, level + 2);
						putLine(lines, level, line);
					}
				}
				generate(code, lines, method, context);
			}
		}
		return code.toString();
	}

	private void generate(StringBuffer code, List<Line> lines, Method method, List<Declare> context) {
		boolean inner = false;
		String tabs = "\t";
		if (code.toString().endsWith("}")) {
			inner = true;
			code = code.delete(code.length() - 1, code.length());
			code.append("\r\n");
			Pattern p = Pattern.compile("[\t]+");
			Matcher m = p.matcher(code.toString());
			while (m.find()) {
				tabs = m.group();
			}

		}
		for (Line line : lines) {
			if (line.isPseudo()) {
				String pseudo = line.getLine().trim();
				// 魔法开始
				if (Pattern.matches("new[\\s][a-zA-Z]+", pseudo.trim())) {
					String clazz = pseudo.replaceAll("new[\\s]", "").trim();
					String generate = String.format("%s %s = new %s();", clazz, clazz.toLowerCase(), clazz);
					code.append(getTab(line.getLevel())).append(generate).append("\r\n");
					context.add(new Declare(clazz, clazz.toLowerCase(), "", ""));

				} else if (Pattern.matches("foreach[\\s][a-zA-Z]+[.][a-zA-Z]+", pseudo.trim())) {
					String param = pseudo.replaceAll("foreach[\\s]", "").trim();
					String[] params = param.split("[.]");
					String clazz = params[0];
					String clazzVar = getNameFromContextByClazz(context, clazz);
					String fieldVar = params[1];
					String fieldClazz = getClassFromContextByRef(context, param);
					String eachClazz = stripClazz(fieldClazz);
					String eachVar = stripClazz(fieldClazz).toLowerCase();
					context.add(new Declare(eachClazz, eachVar, "", ""));
					String generate = String.format("for(%s %s:%s.get%s()){}", eachClazz, eachVar, clazzVar,
							StringUtil.capitalize(fieldVar));
					code.append(getTab(line.getLevel())).append(generate);

				} else if (Pattern.matches("if[\\s][a-zA-Z]+[.][a-zA-Z]+(>=|<=|==|!=|>|<)[a-zA-Z]+[.][a-zA-Z]+",
						pseudo.trim())) {
					String condition = pseudo.replaceAll("if[\\s]", "").trim();
					Pattern p = Pattern.compile("(>=|<=|==|!=|>|<)");
					Matcher m = p.matcher(condition);
					m.find();
					String operation = m.group();
					String[] leftright = condition.split(operation);

					String left = leftright[0];
					String[] params = left.split("[.]");
					String leftClazz = params[0];
					String leftClazzVar = getNameFromContextByClazz(context, leftClazz);
					String leftClazzField = params[1];

					String right = leftright[1];
					params = right.split("[.]");
					String rightClazz = params[0];
					String rightClazzVar = getNameFromContextByClazz(context, rightClazz);
					String rightClazzField = params[1];

					if (getClassFromContextByRef(context, left).equals("BigDecimal")) {
						String generate = String.format("if(%s.get%s().compareTo(%s.get%s()) %s 0){}", leftClazzVar,
								StringUtil.capitalize(leftClazzField), rightClazzVar,
								StringUtil.capitalize(rightClazzField), operation);
						code.append(getTab(line.getLevel())).append(generate);
					} else {
						String generate = String.format("if(%s.get%s() %s %s.get%s()){}", leftClazzVar,
								StringUtil.capitalize(leftClazzField), operation, rightClazzVar,
								StringUtil.capitalize(rightClazzField));
						code.append(getTab(line.getLevel())).append(generate);
					}

				} else if (Pattern.matches("get[\\s][a-zA-Z]+", pseudo.trim())) {
					String clazz = pseudo.replaceAll("get[\\s]", "").trim();
					String ref = clazz + ".id";
					String value = getValueFromContextByDtoRef(context, ref);
					String generate = String.format("%s %s=(%s)baseDao.get(%s.class,%s);", clazz, clazz.toLowerCase(),
							clazz, clazz, value);
					code.append(getTab(line.getLevel())).append(generate).append("\r\n");
					context.add(new Declare(clazz, clazz.toLowerCase(), "", ""));

				} else if (Pattern.matches("save[\\s][a-zA-Z]+", pseudo.trim())) {
					String clazz = pseudo.replaceAll("save[\\s]", "").trim();
					String ClazzVar = getNameFromContextByClazz(context, clazz);
					String generate = String.format("baseDao.save(%s);", ClazzVar);
					code.append(getTab(line.getLevel())).append(generate).append("\r\n");
					context.add(new Declare(clazz, clazz.toLowerCase(), "", ""));

				} else if (Pattern.matches("return[\\s][a-zA-Z]+", pseudo.trim())) {
					String clazz = pseudo.replaceAll("return[\\s]", "").trim();
					String ClazzVar = getNameFromContextByClazz(context, clazz);
					String generate = String.format("return %s;", ClazzVar);
					code.append(getTab(line.getLevel())).append(generate).append("\r\n");
					context.add(new Declare(clazz, clazz.toLowerCase(), "", ""));

				} else if (Pattern.matches(
						"[a-zA-Z]+[.][a-zA-Z]+=[a-zA-Z]+[.][a-zA-Z]+([\\+|\\-|\\*|\\/][a-zA-Z]+[.][a-zA-Z]+)+",
						pseudo.trim())) {
					Pattern p = Pattern.compile("([\\+|\\-|\\*|\\/][a-zA-Z]+[.][a-zA-Z]+)");
					Matcher m = p.matcher(pseudo.trim());
					List<String> strs = new ArrayList<String>();
					while (m.find()) {
						strs.add(m.group());
					}
					String other = "";
					for (String str : strs) {
						other += str;
					}
					String[] leftright = pseudo.trim().replace(other, "").trim().split("[=]");
					String left = leftright[0];
					String[] params = left.split("[.]");
					String leftClazz = params[0];
					String leftClazzVar = getNameFromContextByClazz(context, leftClazz);
					String leftClazzField = params[1];

					String right = leftright[1];
					params = right.split("[.]");
					String rightClazz = params[0];
					String rightClazzVar = getNameFromContextByClazz(context, rightClazz);
					String rightClazzField = params[1];

					StringBuffer operation = new StringBuffer();
					for (String str : strs) {
						String param = str.substring(1);
						params = right.split("[.]");
						String clazz = params[0];
						String clazzVar = getNameFromContextByClazz(context, clazz);
						String clazzField = params[1];
						if (str.startsWith("+")) {
							operation.append(
									String.format(".add(%s.get%s())", clazzVar, StringUtil.capitalize(clazzField)));
						} else if (str.startsWith("-")) {
							operation.append(String.format(".subtract(%s.get%s())", clazzVar,
									StringUtil.capitalize(clazzField)));
						} else if (str.startsWith("*")) {
							operation.append(String.format(".multiply(%s.get%s())", clazzVar,
									StringUtil.capitalize(clazzField)));
						} else if (str.startsWith("/")) {
							operation.append(String.format(".divide(%s.get%s(), 4, RoundingMode.HALF_UP)", clazzVar,
									StringUtil.capitalize(clazzField)));
						}
					}

					String generate = String.format("%s.set%s(%s.get%s()%s);", leftClazzVar,
							StringUtil.capitalize(leftClazzField), rightClazzVar,
							StringUtil.capitalize(rightClazzField), operation);
					code.append(getTab(line.getLevel())).append(generate).append("\r\n");
				} else if (Pattern.matches("[a-zA-Z]+[.][a-zA-Z]+=[a-zA-Z]+[.][a-zA-Z]+", pseudo.trim())) {
					List<String> strs = new ArrayList<String>();
					Pattern p = Pattern.compile("[a-zA-Z]+[.][a-zA-Z]+");
					Matcher m = p.matcher(pseudo.trim());
					while (m.find()) {
						strs.add(m.group());
					}
					String left = strs.get(0);
					String right = strs.get(1);
					String[] params = left.split("[.]");
					String leftClazz = params[0];
					String leftClazzVar = getNameFromContextByClazz(context, leftClazz);
					String leftClazzField = params[1];

					params = right.split("[.]");
					String rightClazz = params[0];
					String rightClazzVar = getNameFromContextByClazz(context, rightClazz);
					String rightClazzField = params[1];
					String generate = String.format("%s.set%s(%s.get%s());", leftClazzVar,
							StringUtil.capitalize(leftClazzField), rightClazzVar,
							StringUtil.capitalize(rightClazzField));
					code.append(getTab(line.getLevel())).append(generate).append("\r\n");

				} else if (Pattern.matches("[a-zA-Z]+[.][a-zA-Z]+=[a-zA-Z]+", pseudo.trim())) {
					String[] leftright = pseudo.trim().split("[=]");

					String left = leftright[0];
					String[] params = left.split("[.]");
					String leftClazz = params[0];
					String leftClazzVar = getNameFromContextByClazz(context, leftClazz);
					String leftClazzField = params[1];

					String rightClazz = leftright[1];
					String rightClazzVar = getNameFromContextByClazz(context, rightClazz);
					String generate = String.format("%s.set%s(%s);", leftClazzVar,
							StringUtil.capitalize(leftClazzField), rightClazzVar);
					code.append(getTab(line.getLevel())).append(generate).append("\r\n");

				} else {
					System.err.println(pseudo.trim());

				}
			} else {
				code.append(line.getLine().trim()).append("\r\n");
			}
			if (line.getChildren().size() > 0) {
				generate(code, line.getChildren(), method, context);
			}
		}
		if (inner) {
			code.append(tabs).append("}").append("\r\n");
		}
	}

	private StringBuffer getTab(int level) {
		StringBuffer tabs = new StringBuffer();
		for (int i = 0; i < level; i++) {
			tabs.append("\t");
		}
		return tabs;
	}

	private String getValueFromContextByDtoRef(List<Declare> context, String dtoRef) {
		String ref = "";
		for (Declare declare : context) {
			if (declare.getDtoRef().equals(dtoRef)) {
				ref = declare.getRef();
				break;
			}
		}
		if (ref.equals("")) {
			return "unknow";
		}
		String var = getNameFromContextByClazz(context, ref.split("[.]")[0]) + ".get"
				+ StringUtil.capitalize(ref.split("[.]")[1]) + "()";
		return var;
	}

	private String getNameFromContextByClazz(List<Declare> context, String clazz) {
		for (Declare declare : context) {
			if (declare.getClazz().equals(clazz)) {
				return declare.getName();
			}
		}
		return "unknow";
	}

	private String getClassFromContextByRef(List<Declare> context, String ref) {
		for (Declare declare : context) {
			if (declare.getRef().equals(ref)) {
				return declare.getClazz();
			}
		}
		return "unknow";
	}

	private void putLine(List<Line> lines, int level, Line line) {
		if (level > 0) {
			putLine(lines.get(lines.size() - 1).getChildren(), level - 1, line);
		} else {
			lines.add(line);
		}
	}
}
